In Elixir, data processing follows two distinct philosophies: Greedy (Eager) and Lazy. Understanding the trade-off is critical for memory efficiency and system stability.
1. The Enumerable Protocol
Technically, things that can be iterated are said to implement the Enumerable protocol. This common contract allows diverse data structures to work with the same set of functions.
2. Greedy vs. Lazy Modules
The Enum module is greedy. It potentially consumes all contents of a collection immediately, creating intermediate lists at every pipeline step. Conversely, the Stream module is lazy. The next value is calculated only when it is needed.
3. Specification vs. Result
A Stream value is a specification of what we intended, but not the result. Streams are enumerable and composable, allowing you to layer transformations without executing work until you pass the stream to an "eager" sink like Enum.to_list/1.
4. Paradigm Purity
Mixing paradigms (functional and object-oriented) dilutes the benefits a functional approach gives you. Prefer declarative transformations over imperative loops for predictability.